package com.zhiyou.interceptor;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import org.aopalliance.intercept.Invocation;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.log4j.Logger;

import com.zhiyou.util.RedisUtil;

public class RedisInterceptor implements MethodInterceptor{

	Logger logger=Logger.getLogger(RedisInterceptor.class);
	private List<String> targetNames;
	private List<String> methodNames;//方法名
	private RedisUtil redisUtil;//redis工具类
	public void setRedisUtil(RedisUtil redisUtil) {
		this.redisUtil = redisUtil;
	}

	//构造方法
	public RedisInterceptor() {
		try {
			//通过初始化方法，知道不需要加入缓存的类和方法有哪些
			File file=new File("E:\\User\\maven_ssm_01\\src\\main\\resources\\redis.properties");
			InputStream is= new FileInputStream(file);
			Properties p=new Properties();//properties：性能，属性
			p.load(is);//加载

			//获取不需要缓存的类和方法
			String[] targets=p.getProperty("targetNames").split(",");
			String[] methods=p.getProperty("methodNames").split(",");

			//把数组转换为集合
			targetNames=new ArrayList<>();
			methodNames=new ArrayList<>();
			for (String target : targets) {
				targetNames.add(target);
			}
			for (String method : methods) {
				methodNames.add(method);
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	//是否加入缓存，需要返回true，不需要返回false
	private boolean isCase(String targetName,String methodName){
		//targetNames存有不需要加入缓存的类的集合
		//methodNames存有不需要加入缓存的方法的集合
		if(targetNames.contains(targetName)||methodNames.contains(methodName)){
			return false;
		}
		return true;
	}

	//设置缓存的键
	//object[] args存有参数的集合
	public String getCacheKey(String tergetName,String methodName,Object[] args){
		//类名_方法名_参数名
		StringBuilder sbd=new StringBuilder(tergetName+"_"+methodName);
		for (Object arg : args) {
			sbd.append("_").append(arg);
		}
		return sbd.toString();
	}



	@Override  //invocation:调用
	public Object invoke(MethodInvocation invocation) throws Throwable {
		//获取类名
		String target=invocation.getThis().getClass().getName();
		//获取方法名
		String method=invocation.getMethod().getName();
		
		if(method.startsWith("insert")||method.startsWith("delete")||method.startsWith("update")){
			//清除缓存
			redisUtil.flushCache();
			return invocation.proceed();//直接执行方法
		}
		
		//判断是否需要加入缓存
		if(!isCase(target, method)){
			return invocation.proceed();
		}
		
		//获取参数
		Object[] args=invocation.getArguments();
		String key=getCacheKey(target, method, args);
		//如果缓存中有，就不需要放入缓存了
		if(redisUtil.exists(key)){
			return redisUtil.get(key);
		}
		Object value=invocation.proceed();//执行查询的方法
		if(value==null){
			return value;
		}
		
		//加入线程
		new Thread(new Runnable() {
			@Override
			public void run() {
				//如果不是null值，需要放入缓存
				redisUtil.set(key, value);
			}
		}).start();
		return value;
	}

}
